﻿namespace CookieTerm
{
    using System;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Xml.Serialization;

    /// <summary>
    /// A centralized storage for display settings
    /// </summary>
    public class DisplaySettings : ICloneable
    {
        public static string[] SupportedEncodings = new string[]
        {
            "us-ascii", "GB18030"
        };

        public static DisplaySettings Default = new DisplaySettings
        {
            Name = "Default",
            Rows = 25,
            Columns = 80,
            EncodingName = "GB18030",
            BlinkingInterval = 750,
            AntiIdle = true,
            FontName = "SimSun",
            FontSize = 16F,
            CursorColor = XmlColor.FromRgb(0xCCCC00),
            Palette = new int[] 
            {
                0x000000, // Black
                0xCC0000, // Red
                0x00CC00, // Green
                0xCCCC00, // Yellow
                0x0000CC, // Blue
                0xCC00CC, // Magenta
                0x00CCCC, // Cyan
                0xCCCCCC, // White
            }.Select(n => XmlColor.FromRgb(n)).ToArray(),
            BoldPalette = new int[] 
            {
                0x666666, // Black
                0xFF6666, // Red
                0x66FF66, // Green
                0xFFFF66, // Yellow
                0x6666FF, // Blue
                0xFF66FF, // Magenta
                0x66FFFF, // Cyan
                0xFFFFFF, // White
            }.Select(n => XmlColor.FromRgb(n)).ToArray(),
        };

        private Encoding encoding;

        public string Name { get; set; }

        public int Rows { get; set; }

        public int Columns { get; set; }

        public string EncodingName { get; set; }

        public uint BlinkingInterval { get; set; }

        public bool AntiIdle { get; set; }

        public string FontName { get; set; }

        public float FontSize { get; set; }

        public XmlColor CursorColor { get; set; }

        public XmlColor[] Palette { get; set; }

        public XmlColor[] BoldPalette { get; set; }

        [XmlIgnore]
        public Encoding Encoding
        {
            get
            {
                if (this.encoding == null)
                {
                    this.encoding = Encoding.GetEncoding(this.EncodingName);
                }

                return this.encoding;
            }
        }

        [XmlIgnore]
        public Tuple<string, float> Font
        {
            get
            {
                return Tuple.Create(this.FontName, this.FontSize);
            }

            set
            {
                this.FontName = value.Item1;
                this.FontSize = value.Item2;
            }
        }

        [XmlIgnore]
        public XmlColor Black
        {
            get
            {
                return this.Palette[0];
            }

            set
            {
                this.Palette[0] = value;
            }
        }

        [XmlIgnore]
        public XmlColor Red
        {
            get
            {
                return this.Palette[1];
            }

            set
            {
                this.Palette[1] = value;
            }
        }

        [XmlIgnore]
        public XmlColor Green
        {
            get
            {
                return this.Palette[2];
            }

            set
            {
                this.Palette[2] = value;
            }
        }

        [XmlIgnore]
        public XmlColor Yellow
        {
            get
            {
                return this.Palette[3];
            }

            set
            {
                this.Palette[3] = value;
            }
        }

        [XmlIgnore]
        public XmlColor Blue
        {
            get
            {
                return this.Palette[4];
            }

            set
            {
                this.Palette[4] = value;
            }
        }

        [XmlIgnore]
        public XmlColor Magenta
        {
            get
            {
                return this.Palette[5];
            }

            set
            {
                this.Palette[5] = value;
            }
        }

        [XmlIgnore]
        public XmlColor Cyan
        {
            get
            {
                return this.Palette[6];
            }

            set
            {
                this.Palette[6] = value;
            }
        }

        [XmlIgnore]
        public XmlColor White
        {
            get
            {
                return this.Palette[7];
            }

            set
            {
                this.Palette[7] = value;
            }
        }

        [XmlIgnore]
        public XmlColor BoldBlack
        {
            get
            {
                return this.BoldPalette[0];
            }

            set
            {
                this.BoldPalette[0] = value;
            }
        }

        [XmlIgnore]
        public XmlColor BoldRed
        {
            get
            {
                return this.BoldPalette[1];
            }

            set
            {
                this.BoldPalette[1] = value;
            }
        }

        [XmlIgnore]
        public XmlColor BoldGreen
        {
            get
            {
                return this.BoldPalette[2];
            }

            set
            {
                this.BoldPalette[2] = value;
            }
        }

        [XmlIgnore]
        public XmlColor BoldYellow
        {
            get
            {
                return this.BoldPalette[3];
            }

            set
            {
                this.BoldPalette[3] = value;
            }
        }

        [XmlIgnore]
        public XmlColor BoldBlue
        {
            get
            {
                return this.BoldPalette[4];
            }

            set
            {
                this.BoldPalette[4] = value;
            }
        }

        [XmlIgnore]
        public XmlColor BoldMagenta
        {
            get
            {
                return this.BoldPalette[5];
            }

            set
            {
                this.BoldPalette[5] = value;
            }
        }

        [XmlIgnore]
        public XmlColor BoldCyan
        {
            get
            {
                return this.BoldPalette[6];
            }

            set
            {
                this.BoldPalette[6] = value;
            }
        }

        [XmlIgnore]
        public XmlColor BoldWhite
        {
            get
            {
                return this.BoldPalette[7];
            }

            set
            {
                this.BoldPalette[7] = value;
            }
        }

        public object Clone()
        {
            StringWriter writer = new StringWriter();
            XmlSerializer serializer = new XmlSerializer(this.GetType());
            serializer.Serialize(writer, this);
            string s = writer.ToString();
            StringReader reader = new StringReader(s);
            return serializer.Deserialize(reader);
        }
    }
}